using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;


namespace WindowsGame3
{
    


    


    public class Game1 : Microsoft.Xna.Framework.Game
    {

        Vector2 PlayField;
        Vector2 rectangletemplate;

        int screenWidth = 1024;
        int screenHeight = 768;
        

        Color colorOfblocK; //might remove, hard coding right now for new block inside block feature
        
        
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;


        public Vector2 Position;


        public int movehorizontal = 0;


        public static bool diagnosticmode = false;
        
        
        int y = 0;
        
        int xItereateofPieceWidthforBlockCreate = 0; //Iterates by width of block in block2.cs to create blocks over horizontally correctly
        Vector2[] vector2ArrayOfRectangleCoordsToDrawPiece = new Vector2[4]; // Array to hold the rectangle xy's to be drawn.
        Vector2 XY_OfCurrentRectangleToBeDrawn; //this is a vector of the pieace the single block, single rectangle to draw
        
        float timer = 0f;
        float interval = 500.0f; //.5 Second
        int count = 0;
        int ii = 0;

        static Vector2 ScreenResolution;
       

        Vector3[,] BlockVectorhistory = new Vector3[10, 20];
        Vector3[,] v3ofPiecestoDraw = new Vector3[10, 20];
        bool piecelanded = false;
        
        SpriteFont font;
        //int randomizer = 1;

        private float fps;
        private float updateinterval = 1.0f;
        private float timeSinceLastUpdate = 0.0f;
        private float framecount = 0;


        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        
        protected override void Initialize()
        {
            Window.Title = "Tetris Concept";
            base.Initialize();
            
            ScreenResolution.Y = screenHeight;
            ScreenResolution.X = screenWidth;

            
        
            int PlayFieldHeight = screenHeight -100 ;
            int PlayFieldWidth = screenWidth - 500;

            
            int heightOfRectangleToBeDrawn = PlayFieldHeight / 20;
            int widthOfRectangleToBeDrawn = PlayFieldWidth / 10;
            int scale = heightOfRectangleToBeDrawn;
            graphics.IsFullScreen = false;
            graphics.PreferredBackBufferHeight = screenHeight;
            graphics.PreferredBackBufferWidth = screenWidth;
            graphics.SynchronizeWithVerticalRetrace = false;
            IsFixedTimeStep = false;
            graphics.ApplyChanges();

        }

        
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            font = Content.Load<SpriteFont>("myFont");
            // TODO: use this.Content to load your game content here
            
            
        }

        
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            // TODO: Add your update logic here
            timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
            
            //GetKeyboard();
            updateBlock();
            base.Update(gameTime);
        }

      
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.PaleGoldenrod);

            // TODO: Add your drawing code here

            fpsupdate(gameTime);



            spriteBatch.Begin();
            DrawPlayfield();
            drawBlock();
            spriteBatch.End();

            base.Draw(gameTime);
        }

       

        //Sets the blocks coordinates based on the return of XY and then draws them calling CreateRectangle Method

        public void drawBlock()
        {
            if (piecelanded)
            {
                //Array.Copy(v3ofPiecestoDraw, BlockVectorhistory, 10);
                //BlockVectorhistory = VectorArray_OfPiecesToDrawOnScreen;

                y = 0;
                xItereateofPieceWidthforBlockCreate = 0;
                piecelanded = false;
            }

            else
            {
                //VectorArray_OfPiecesToDrawOnScreen = BlockVectorhistory;
                //Array.Copy(BlockVectorhistory, v3ofPiecestoDraw,v3ofPiecestoDraw.Length);
            }

            vector2ArrayOfRectangleCoordsToDrawPiece = new block2().BuldingNextPiece(y, xItereateofPieceWidthforBlockCreate, movehorizontal);


            foreach (Vector2 element2 in vector2ArrayOfRectangleCoordsToDrawPiece)
            {
                int blockWidthIncreiment = widthOfRectangleToBeDrawn; // I did this to keep better track of where code was failing
                int blockHeightIncriment = heightOfRectangleToBeDrawn; // had too many linked vars and didnt know what was updating when.

                for (int BVintX = 0; BVintX <= 9; BVintX++) //iterate X to control left to right
                {

                    for (int BVintY = 0; BVintY <= 19; BVintY++) //itterate Yaxis by heigh of piece to control block placement
                    {

                        v3ofPiecestoDraw[BVintX, BVintY].X = blockWidthIncreiment;
                        v3ofPiecestoDraw[BVintX, BVintY].Y = blockHeightIncriment;
                        if (element2.X == blockWidthIncreiment && element2.Y == blockHeightIncriment)
                        {
                            v3ofPiecestoDraw[BVintX, BVintY].Z = 1; // if 1 draw piece in all modes
                            //BVintY = 19;
                        }
                        else
                        {
                            v3ofPiecestoDraw[BVintX, BVintY].Z = 0; //0 = means no piece in normal mode
                        }

                        blockHeightIncriment += heightOfRectangleToBeDrawn; //incriment Y up by height of piece
                    }

                    blockWidthIncreiment += widthOfRectangleToBeDrawn; //incriment x axis by width ammount
                    blockHeightIncriment = heightOfRectangleToBeDrawn; //reset heigh back to base 

                }


                //Vector2 vBlock;

                foreach (Vector3 v3Block in v3ofPiecestoDraw) //for each vector3 from the above code, get x y and z into v3block.x.y.z
                {
                    diagnosticmode = false ;
                    switch (v3Block.Z > 0) // IF Z = 1 then draw a piece
                    {
                        case true:
                            XY_OfCurrentRectangleToBeDrawn.Y = v3Block.Y ;
                            XY_OfCurrentRectangleToBeDrawn.X = v3Block.X ;
                            colorOfblocK = Color.Orange;
                            CreateRectangle();
                            
                            

                            

                            break;
                        
                        case false:
                            if (diagnosticmode)
                            {
                                XY_OfCurrentRectangleToBeDrawn.Y = v3Block.Y;
                                XY_OfCurrentRectangleToBeDrawn.X = v3Block.X;
                                colorOfblocK = Color.Green;
                                CreateRectangle();
                            }
                            break;
                    }
                    
                }
            }
        }


        private void updateBlock()
        {
           
            if ((y + heightOfRectangleToBeDrawn) <= (heightOfRectangleToBeDrawn * 19))
            {
            //    drawnXY.Y = y+ y + scale;
                GetKeyboard();
                if (timer > interval)
                {
                    y += heightOfRectangleToBeDrawn;
                    timer = 0f;
                }

               // y += heightOfRectangleToBeDrawn;

                // Moves the block down, timer executes this on an interval
            } 
            else
            {
                movehorizontal = 0;
                piecelanded = true;
            }
        }


        public void CreateRectangle()
        {

            Texture2D rectangleTexture;
            Color[] color;

            for (int block3dEffectitterater = 0; block3dEffectitterater < 2; block3dEffectitterater++)
            {

                if (block3dEffectitterater == 0)
                {


                    rectangleTexture = new Texture2D(GraphicsDevice, widthOfRectangleToBeDrawn, heightOfRectangleToBeDrawn, 1, TextureUsage.None, SurfaceFormat.Color);

                    color = new Color[widthOfRectangleToBeDrawn * heightOfRectangleToBeDrawn];//set the color to the amount of pixels

                    for (int i = 0; i < color.Length; i++)//loop through all the colors setting them to whatever values we want
                    {
                        color[i] = new Color(255, 255, 255, 253);
                        if (ii < 255)
                            ii++;
                    }

                    rectangleTexture.SetData(color);//set the color data on the texture
                    spriteBatch.Draw(rectangleTexture, XY_OfCurrentRectangleToBeDrawn, Color.Red);


                    //spriteBatch.Draw(rectangleTexture, XY_OfCurrentRectangleToBeDrawn, colorOfblocK);
                    
                    count++;
                }
            
            else 
            {
                 int widthOfRectangleToBeDrawn2 = widthOfRectangleToBeDrawn - 2;
                 int heightOfRectangleToBeDrawn2 = heightOfRectangleToBeDrawn - 2;
   
                 XY_OfCurrentRectangleToBeDrawn.X += 1;
                 XY_OfCurrentRectangleToBeDrawn.Y += 1;


                 Texture2D rectangleTexture2 = new Texture2D(GraphicsDevice, widthOfRectangleToBeDrawn2, heightOfRectangleToBeDrawn2, 1, TextureUsage.None, SurfaceFormat.Color);

                    color = new Color[widthOfRectangleToBeDrawn2 * heightOfRectangleToBeDrawn2];//set the color to the amount of pixels

                    for (int i = 0; i < color.Length; i++)//loop through all the colors setting them to whatever values we want
                    {
                        color[i] = new Color(255, 255, 255,190);
                        if (ii < 255)
                            ii++;
                    }

                    rectangleTexture2.SetData(color);//set the color data on the texture
                    spriteBatch.Draw(rectangleTexture2, XY_OfCurrentRectangleToBeDrawn, Color.Blue);


                    //spriteBatch.Draw(rectangleTexture, XY_OfCurrentRectangleToBeDrawn, colorOfblocK);
                    spriteBatch.DrawString(font, XY_OfCurrentRectangleToBeDrawn.ToString(), XY_OfCurrentRectangleToBeDrawn, Color.White);
            }
         }


        }

        private void GetKeyboard()
        {
            KeyboardState kbstate = Keyboard.GetState();
            if(kbstate.IsKeyDown(Keys.Left))
            {

                if ((xItereateofPieceWidthforBlockCreate  - widthOfRectangleToBeDrawn ) >= widthOfRectangleToBeDrawn)
                movehorizontal -= widthOfRectangleToBeDrawn;
            }
            
            else if (kbstate.IsKeyDown(Keys.Right))
            {
                if (xItereateofPieceWidthforBlockCreate  + widthOfRectangleToBeDrawn <= widthOfRectangleToBeDrawn * 7)
                movehorizontal += widthOfRectangleToBeDrawn;
            }
        }

        //Draw the flat colord square that makes up the actual play area of the screen
        private void DrawPlayfield()
        {

            {

                Texture2D rectangleTexture = new Texture2D(GraphicsDevice, PlayFieldWidth, PlayFieldHeight, 1, TextureUsage.None, SurfaceFormat.Color);

                Color[] color = new Color[PlayFieldWidth * PlayFieldHeight];//set the color to the amount of pixels

                for (int i = 0; i < color.Length; i++)//loop through all the colors setting them to whatever values we want
                {
                    color[i] = new Color(0, 255, 255, 255);
                    if (ii < 255)
                    ii++;
                }

                XY_OfCurrentRectangleToBeDrawn.X = widthOfRectangleToBeDrawn;
                XY_OfCurrentRectangleToBeDrawn.Y = heightOfRectangleToBeDrawn ;

                rectangleTexture.SetData(color);//set the color data on the texture
                spriteBatch.Draw(rectangleTexture, XY_OfCurrentRectangleToBeDrawn,Color.Black);
              
            }

        }


        private void fpsupdate(GameTime gameTime)
        {
            float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
            framecount++;
            timeSinceLastUpdate += elapsed;

            if (timeSinceLastUpdate > updateinterval)
            {
                fps = framecount / timeSinceLastUpdate; //mean fps over updateInterval

                Window.Title = "FPS: " + fps.ToString() + " - RT: " +
                    gameTime.ElapsedGameTime.TotalSeconds.ToString() + " - GT: " +
                    gameTime.ElapsedGameTime.TotalSeconds.ToString();

                framecount = 0;
                timeSinceLastUpdate -= updateinterval;
            }
        }
    }
}
